package com.design.patterns.creativeModel.decorator;

import com.design.patterns.creativeModel.decorator.service.News;
import com.design.patterns.creativeModel.decorator.service.Notice;
import com.design.patterns.creativeModel.decorator.service.decorator.QQDecorator;
import com.design.patterns.creativeModel.decorator.service.decorator.WechatDecorator;

/**
 * 装饰器模式
 * 目的：动态地给一个对象添加一些额外的职责。就增加功能来说，相比生成子类更为灵活。
 *
 * 装饰器（Decorator）模式，是一种在运行期动态给某个对象的实例增加功能的方法。
 *
 * 我们在IO的Filter模式一节中其实已经讲过装饰器模式了。
 * 在Java标准库中，InputStream是抽象类，FileInputStream、ServletInputStream、Socket.getInputStream()这些InputStream都是最终数据源。
 * 现在，如果要给不同的最终数据源增加缓冲功能、计算签名功能、加密解密功能，那么，3个最终数据源、3种功能一共需要9个子类。
 * 如果继续增加最终数据源，或者增加新功能，子类会爆炸式增长，这种设计方式显然是不可取的。
 * Decorator模式的目的就是把一个一个的附加功能，用Decorator的方式给一层一层地累加到原始数据源上，最终，通过组合获得我们想要的功能。
 */
public class DecoratorMain {
    public static void main(String[] args) {
        /**
         * 我们将装饰者模式转化成抽象的行为
         * 我们现在有个需求，推送通知类：向对应软件推送通知，我们现在假设有qq，微信，支付宝
         * 现在我们先写一个基础的通知类，然后再去增强他（使用装饰者模式）
         */
        /**
         * 先定义一个接口，说明通知抽象方法Notice申明具体方法
         * 其次定义实现类News，定义基础的消息的核心
         * 为了实现Decorator模式，需要有一个抽象的Decorator类：NewsDecorator
         * 后续的实现Decorator模式只需要去继承NewsDecorator后就可以实现装饰者模式
         */
        Notice news = new News();
        Notice news2 = new QQDecorator(new News());
        Notice wechatDecorator = new WechatDecorator(new News());
        Notice news3 = new QQDecorator(new WechatDecorator(new News()));
        news.push("测试普通");
        news2.push("测试增强");
        wechatDecorator.push("测试增强wx");
        news3.push("测试增强wx+qq");



        System.out.println(news.pull());
        System.out.println(news2.pull());
        System.out.println(wechatDecorator.pull());
        System.out.println(news3.pull());
    }
}
